/** Data file containing definitions for all spells.
 *
 * This is a hash of hashes. Each hash contains the property bag that is the
 * argument to the Spell.init method for the spell identified by that hash key.
 */

// Common funtions for spells
var _spellFunc = {
	hitCheck: {
		melee: function(source, target, skill) {
			var at = 50 + source["_skill_" + skill] * 2 - target["_skill_defense"] * 2;
			if(at < 5)
				at = 5;
			if(at > 95)
				at = 95;
			return rand.d100() <= at;
		},
		ranged: function(source, target) {
			var at = 6 + (target.level - source.level) * 2 + (target.dex - source.dex) + target.ac;
			return rand.d20() >= at;
		}
	},
	apply: {
		all: function(source, target, effects) {
			for(var i = 0; i < effects.length; ++i)
			{
				target.addEffect(effects[i]);
			}
		}
	},
	message: function(source, target, verb, post, ifPlayer, ifNotPlayer, damage, punctuation) {
		var msg = "";
		if(source === dhack.player)
			msg = "%" + Color.codesByNumber[ifPlayer] + "0";
		else
			msg = "%" + Color.codesByNumber[ifNotPlayer] + "0";
		var first, second;
		if(source === target)
		{
			if(source === dhack.player)
			{
				first = "You";
				second = "yourself";
			}
			else
			{
				first = source.getMessageName(true);
				second = "itself";
			}
		}
		else
		{
			first = source.getMessageName(true);
			if(target !== null)
				second = target.getMessageName(false);
		}
		msg += first + " " + verb;
		if(target !== null)
			msg += " " + second;
		if(post)
			msg += " " + post;
		if(damage)
			msg += " [" + damage + "]";
		if(punctuation)
			msg += punctuation;
		dhack.logWindow.pushMessage(msg);
	}
}

var spells =
{
/*
 *
 * Melee Combat
 *
 */
"attack": {
	name: "Attack",
	target: "melee",
	getEffects: function(source) {
		return [new Effect({
			name: "Damage",
			type: "attack",
			mods: {
				sp: source.getMeleeDamage() * -1
			}
		})];
	},
	apply: function(source, target) {
		if(_spellFunc.hitCheck.melee(source, target, "fighting"))
		{
			var e = this.getEffects(source);
			_spellFunc.apply.all(source, target, e);
			target.wasHitBy(source);
			_spellFunc.message(source, target, "hit", "", Color.green, Color.red, 0, "!");
		}
		else
		{
			target.wasHitBy(source);
			_spellFunc.message(source, target, "missed", "", Color.yellow, Color.green, 0, ".");
		}
	}},
"ranged attack": {
	name: "Ranged Attack",
	target: "ranged",
	getEffects: function(source) {
		return [new Effect({
			name: "Damage",
			type: "attack",
			mods: {
				hp: (source.rdmg + (rand.next(0, Math.ceil(source.rdmg / 2)) - Math.floor(source.rdmg / 4))) * -1
			}
		})];
	},
	apply: function(source, target) {
		if(_spellFunc.hitCheck.ranged(source, target))
		{
			var e = this.getEffects(source);
			_spellFunc.apply.all(source, target, e);
			target.wasHitBy(source);
			_spellFunc.message(source, target, "hit", "", Color.green, Color.red, e[0].mods.hp * -1, "!");
		}
		else
		{
			target.wasHitBy(source);
			_spellFunc.message(source, target, "missed", "", Color.yellow, Color.green, 0, "!");
		}
	}},
"heal": {
	name: "Heal",
	target: "self",
	getEffects: function(source) {
		return [new Effect({	
			name: "Heal",
			type: "attack",
			mods: {
				hp: (source.hpMax * this.param) | 0
			}
		})];
	},
	apply: function(source, target) {
		var e = this.getEffects(source);
		_spellFunc.apply.all(source, target, e);
		_spellFunc.message(source, target, "healed", "", Color.green, Color.red, e[0].mods.hp);
	}},
"mana": {
	name: "Mana",
	target: "self",
	getEffects: function(source) {
		return [new Effect({	
			name: "Restore Mana",
			type: "attack",
			mods: {
				mp: (source.mpMax * this.param) | 0
			}
		})];
	},
	apply: function(source, target) {
		var e = this.getEffects(source);
		_spellFunc.apply.all(source, target, e);
		_spellFunc.message(source, target, "restored mana to", "", Color.green, Color.yellow, e[0].mods.hp);
	}},
"haste": {
	name: "Haste",
	target: "self",
	getEffects: function(source) {
		return [new Effect({
			name: "Haste",
			type: "buff",
			duration: this.param.duration,
			mods: {
				speed: this.param.speed
			}
		})];
	},
	apply: function(source, target) {
		var e = this.getEffects(source);
		_spellFunc.apply.all(source, target, e);
		_spellFunc.message(source, target, "hasten", "", Color.green, Color.yellow, 0, "!");
	}},
"berzerk": {
	name: "Berzerker",
	target: "self",
	getEffects: function(source) {
		return [new Effect({
			name: "Berzerker Rage",
			type: "buff",
			duration: this.param,
			mods: {
				str: 5,
				dmg: 7,
				rdmg: 5,
				dex: -5,
				con: -5,
				intel: -5
			}
		}),
		new Effect({
			name: "Haste",
			type: "buff",
			duration: this.param,
			mods: {
				speed: 20
			}
		})];
	},
	apply: function(source, target) {
		var e = this.getEffects(source);
		_spellFunc.apply.all(source, target, e);
		_spellFunc.message(source, null, (source === dhack.player ? "go berzerk" : "goes berzerk"), "", Color.green, Color.red, 0, "!");
	}},
"fireball": {
	name: "Fireball",
	target: "ranged",
	range: 10,
	getEffects: function(source) {
		return [new Effect({
			name: "Fire Damage",
			type: "attack",
			mods: {
				hp: util.floor(this.param + (source.intel - 10) * 2, 5) * -1
			}
		})];
	},
	apply: function(source, target) {
		var e = this.getEffects(source);
		_spellFunc.apply.all(source, target, e);
		_spellFunc.message(source, target, "engulf", "in flames", Color.green, Color.yellow, e[0].mods.hp * -1, "!");
	}}
};

delete f;
